package com.cos.lession72.advices;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author: COS
 * @time: 2022/9/28 9:27
 * @description:
 * @Aspect 声明这个类是切面类(aop的增强)
 * @Component 把这个类交给spring管理
 * 1. application.xml 要配置aop注解驱动
 * 2. 配置写这个类注解
 *      @Aspect
 *      @Component
 * 3.写一个空方法,设置切点表达式
 * 4.写增强方法
 *      形参JoinPoint 就是用于获取,目标类,目标方法,目标方法的参数列表 ,除了环绕都可以使用他
 *      ProceedingJoinPoint 环绕增强使用的,必须使用因为环绕增强需要放行
 */
@Aspect
@Component
public class MyAdvices {
    /**
     * @author: COS
     * @return:
     * @time: 2022/9/28 9:32
     * @description: 设置空方法, 唯一作用, 作为切点使用
     * 在上面写切点注解,想要使用这个切点
     * 表达式,把方法名()提供,这个方法就代表着注解的切点表达式
     */
    @Pointcut("execution(* com.cos.lession72.services..*.*(..))")
    public void pointCut() {
    }

    /**
     * @author: COS
     * @return:
     * @time: 2022/9/28 9:33
     * @description: Before 前置增强
     * @Before("pointCut()") 切点表达式就在 pointCut() 方法上,引用这个切点表达式
     */
    @Before("pointCut()")
    public void t1(JoinPoint joinPoint) {
        System.out.println("前置增强");
        System.out.println(joinPoint.getSignature().getName());
        System.out.println(joinPoint.getArgs());
    }
    /**
     *
     * @author: COS
     * @return:
     * @time: 2022/9/28 9:45
     * @description:
     * 后置增强
     * @AfterReturning(
     * pointcut = "pointCut()", 设置切点表达式
     * returning = "returnValue" 设置告知spring 形参名为returnValue,是要接受方法的返回值的一个形参
     * )
     */
    @AfterReturning(pointcut = "pointCut()",returning = "returnValue")
    public void t2(JoinPoint joinPoint,Object returnValue){
        System.out.println("后置增强");
        System.out.println("返回值是:"+returnValue);
    }

    @Around("pointCut()")
    public Object t3(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("环绕前置");
        // 放行
        Object proceed = jp.proceed();
        System.out.println("环绕后置");
//        proceed=null;
        return proceed;
    }
    @AfterThrowing(pointcut = "pointCut()",throwing = "ex")
    public void t4(JoinPoint jp, Exception ex){
        System.out.println("异常");
//        ex.printStackTrace();
        System.out.println(jp.getSignature().getName()+",出现异常:"+ex.getMessage()+",time:"+new Date());
    }


    @Before("pointCut()")
    public void t5(JoinPoint joinPoint) {
        System.out.println("前置增强2222222222222222222222222222");
        System.out.println(joinPoint.getSignature().getName());
        System.out.println(joinPoint.getArgs());
    }
}
